package cn.sylinx.horm.dialect.sql;

import cn.sylinx.horm.dialect.fs.FS;
import cn.sylinx.horm.dialect.fs.PlainFS;
import cn.sylinx.horm.model.cache.ModelCacheUtil;
import cn.sylinx.horm.model.cache.ModelFabric;
import cn.sylinx.horm.type.handler.TypeHandler;
import cn.sylinx.horm.util.Pair;
import cn.sylinx.horm.util.Tuple;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class SqlBuilder {

    /**
     * 获取分页sql
     * 
     * @param preSql
     * @param pageNumber
     * @param pageSize
     * @return Tuple 0：获取总行数sql，1：查询数据sql，3：分页参数
     */
    abstract public Tuple buildPaginatorSql(String preSql, int pageNumber, int pageSize);

    /**
     * 构建删除sql
     * 
     * @param t
     * @return
     */
    abstract public <T> Pair buildDeleteSQL(T t);

    /**
     * 构建插入sql
     * 
     * @param t
     * @return
     */
    abstract public <T> Pair buildInsertSQL(T t);

    /**
     * 生成批量插入sql
     * 
     * @param <T>
     * @param dataList
     * @return
     */
    abstract public <T> Pair buildBatchInsertSQL(List<T> dataList);

    /**
     * 构建更新sql
     * 
     * @param t
     * @return
     */
    abstract public <T> Pair buildUpdateSQL(T t);

    /**
     * 构建根据字段删除sql
     * 
     * @param kvList
     * @param clz
     * @return
     */
    abstract public Pair buildDeleteByFieldSQL(List<Pair> kvList, Class<?> clz);

    /**
     * 构建根据字段查询sql
     * 
     * @param kvList
     * @param clz
     * @return
     */
    abstract public Pair buildQueryByFieldSQL(List<Pair> kvList, Class<?> clz);

    /**
     * 构建根据字段查询sql
     * 
     * @param kvList
     * @param clz
     * @param fields
     * @return
     */
    abstract public Pair buildQueryByFieldSQL(List<Pair> kvList, Class<?> clz, String[] fields);

    /**
     * 构建简单查询 select * from table
     * 
     * @param clz
     * @return
     */
    abstract public String buildSimpleQuery(Class<?> clz);

    /**
     * 构建简单查询 select field_name from table
     * 
     * @param clz
     * @param fields
     * @return
     */
    abstract public String buildSimpleQuery(Class<?> clz, String[] fields);

    /**
     * 获取表对象
     * 
     * @param clz
     * @return
     */
    abstract public String getTable(Class<?> clz);

    /**
     * 获取表列名称
     * 
     * @param clz
     * @param prop
     * @return
     */
    abstract public String getTableColumn(Class<?> clz, String prop);

    /**
     * 创建表ddl
     * 
     * @param clz
     * @return
     */
    abstract public String[] buildCreateTableDDL(Class<?> clz);

    /**
     * 合法检测语句
     * 
     * @return
     */
    abstract public String buildValidateQuery();

    public Tuple buildSelectSQL(FS<?> fluentSql) {
        return DefaultFlusentSqlBuildHelper.buildSelectSQL(fluentSql);
    }

    public Pair buildUpdateSQL(FS<?> fluentSql) {
        return DefaultFlusentSqlBuildHelper.buildUpdateSQL(fluentSql);
    }

    public Pair buildInsertSQL(FS<?> fluentSql) {
        return DefaultFlusentSqlBuildHelper.buildInsertSQL(fluentSql);
    }

    public Pair buildDeleteSQL(FS<?> fluentSql) {
        return DefaultFlusentSqlBuildHelper.buildDeleteSQL(fluentSql);
    }

    public Pair buildCountSQL(FS<?> fluentSql) {
        return DefaultFlusentSqlBuildHelper.buildCountSQL(fluentSql);
    }

    public Tuple buildSelectSQL(PlainFS fluentSql) {
        return DefaultPlainFlusentSqlBuildHelper.buildSelectSQL(fluentSql);
    }

    public Pair buildUpdateSQL(PlainFS fluentSql) {
        return DefaultPlainFlusentSqlBuildHelper.buildUpdateSQL(fluentSql);
    }

    public Pair buildInsertSQL(PlainFS fluentSql) {
        return DefaultPlainFlusentSqlBuildHelper.buildInsertSQL(fluentSql);
    }

    public Pair buildDeleteSQL(PlainFS fluentSql) {
        return DefaultPlainFlusentSqlBuildHelper.buildDeleteSQL(fluentSql);
    }

    public Pair buildCountSQL(PlainFS fluentSql) {
        return DefaultPlainFlusentSqlBuildHelper.buildCountSQL(fluentSql);
    }

    protected Object convertValue(TypeHandler<?> typeHandler, Object v) {
        return DefaultFlusentSqlBuildHelper.convertValue(typeHandler, v);
    }
}
